import java.awt.event.KeyEvent;
import java.util.ArrayList;

public class NeuronEventProcessor extends DrawObjectEventProcessor
{
	@Override
	public void TryProcessUserKeyboardAction(MainWindow.GUIElements GUIElements, KeyEventProcessor KeyEventProcessor, MouseEventProcessor MouseEventProcessor, ObjectStorage ObjectStorage, IOProgram IOProgram)
	{
		if (!(KeyboardEventsToBeProcessed(GUIElements)))
			return;

		// ****************************************************************
		// 1-9 (toggle Strength of NeuronInputField 0-8)
		for (int InputFieldIndex = 0; InputFieldIndex < 9; InputFieldIndex++)
		{
			if (KeyEventProcessor.IsKeyTyped((char) ('1' + InputFieldIndex)))
			{
				if (MultiSelectionExisting)
				{
					ArrayList<DrawObject> SelectedObjects = ObjectStorage.GetMultiSelectionObjects();

					ObjectStorage.ToggleNeuronInputFieldByIndex(SelectedObjects, InputFieldIndex);

					GUIElements.GetMainWindow().DoRedraw();
				}
			}
		}
		// ****************************************************************
		// h (assign Hormone to Neuron)
		if (KeyEventProcessor.IsKeyCodePressed(KeyEvent.VK_H) &&
			KeyEventProcessor.IsControlPressed())
		{
			if (GUIElements.GetMainWindow().hasFocus())
			{
				if (MultiSelectionExisting || DEFINED(NearObject))
				{
					String HormoneName = Tools.ShowInputDialog("Hormone name? ('DEL '/'REN ' in front of existing name to remove/rename)");
					if (HormoneName != null && HormoneName.length() >= 1)
					{
						boolean Del = HormoneName.toUpperCase().startsWith("DEL ");
						boolean Ren = HormoneName.toUpperCase().startsWith("REN ");

						String HormoneNameNew = "[internal error]";
						if (Ren)
						{
							HormoneNameNew = Tools.ShowInputDialog("New Hormone name?");
						}
						if (Del || (Ren && HormoneNameNew != null && HormoneNameNew.length() >= 1))
						{
							HormoneName = HormoneName.substring(4); // remove "DEL " or "REN "

							if (MultiSelectionExisting)
							{
								ArrayList<DrawObject> MultiSelectionObjects = ObjectStorage.GetMultiSelectionObjects();

								for (int m = 0; m < MultiSelectionObjects.size(); m++)
								{
									DrawObject o = MultiSelectionObjects.get(m);
									if (o.IsNeuron())
									{
										if (Del)
										{
											((Neuron) o).DeleteHormone(HormoneName);
										}
										if (Ren)
										{
											((Neuron) o).ReplaceHormoneName(HormoneName, HormoneNameNew);
										}
									}
								}
							}
							else if (DEFINED(NearObject))
							{
								ArrayList<DrawObject> ObjectsContainingHormone = ObjectStorage.GetObjectsContainingHormone(HormoneName);

								if (ObjectsContainingHormone.size() == 0)
								{
									Tools.ShowMessageDialog(GUIElements.GetMainWindow(), "No such Hormone found!");
								}
								if (ObjectsContainingHormone.size() >= 1)
								{
									if (Del)
									{
										if (ObjectsContainingHormone.size() > 1 && Tools.ShowYesNoDialog(GUIElements.GetMainWindow(), "Multiple Neurons use this Hormone. Delete from all?"))
										{
											ObjectStorage.DeleteHormoneForAll(HormoneName);
										}
										else
										{
											((Neuron) NearObject).DeleteHormone(HormoneName);
										}
									}
									if (Ren)
									{
										if (ObjectsContainingHormone.size() > 1 && Tools.ShowYesNoDialog(GUIElements.GetMainWindow(), "Multiple Neurons use this Hormone. Rename in all?"))
										{
											ObjectStorage.ReplaceHormoneNameForAll(HormoneName, HormoneNameNew);
										}
										else
										{
											((Neuron) NearObject).ReplaceHormoneName(HormoneName, HormoneNameNew);
										}
									}
								}
							}
						}
						else
						{
							if (MultiSelectionExisting)
							{
								ArrayList<DrawObject> MultiSelectionObjects = ObjectStorage.GetMultiSelectionObjects();

								for (int m = 0; m < MultiSelectionObjects.size(); m++)
								{
									DrawObject o = MultiSelectionObjects.get(m);
									if (o.IsNeuron())
									{
										if (((Neuron) o).GetHormoneStrength(HormoneName) == Double.MAX_VALUE)
										{
											((Neuron) o).AddHormone(HormoneName);
										}
									}
								}
							}
							else if (DEFINED(NearObject))
							{
								if (((Neuron) NearObject).GetHormoneStrength(HormoneName) == Double.MAX_VALUE)
								{
									((Neuron) NearObject).AddHormone(HormoneName);
								}
								else
								{
									Tools.ShowMessageDialog(null, "Hormone already existing, add again with name\r\n'DEL " + HormoneName + "' to remove or 'REN " + HormoneName + "' to rename.");
								}
							}
						}
						
						GUIElements.GetMainWindow().DoRedraw();
					}
				}
			}
		}
		// ****************************************************************
		// n (negate NeuronInputField)
		if (KeyEventProcessor.IsKeyTyped('n'))
		{
			if (MultiSelectionExisting)
			{
				ArrayList<DrawObject> MultiSelectionObjects = ObjectStorage.GetMultiSelectionObjects();

				for (int m = 0; m < MultiSelectionObjects.size(); m++)
				{
					DrawObject o = MultiSelectionObjects.get(m);
					if (o.IsSampleAndHold())
					{
						((SampleAndHold) o).ToggleIsNegative();
					}
				}

				GUIElements.GetMainWindow().DoRedraw();
			}
			else if (DEFINED(NearObject))
			{
				if (NearObject.IsNeuron())
				{
					((Neuron) NearObject).ToggleIsNegative(DrawObject.UnZoomPoint(MouseEventProcessor.GetMousePosPoint(GUIElements.GetMainWindow())));

					GUIElements.GetMainWindow().DoRedraw();
				}
				if (NearObject.IsNeuronInputField()) // field is now also supported as various DrawObject looping orders changed
				{
					((NeuronInputField) NearObject).ToggleIsNegative();

					GUIElements.GetMainWindow().DoRedraw();
				}
			}
		}

		return;
	}

	@Override
	public void TryProcessUserMouseAction(MainWindow.GUIElements GUIElements, KeyEventProcessor KeyEventProcessor, MouseEventProcessor MouseEventProcessor, ObjectStorage ObjectStorage, IOProgram IOProgram)
	{
		if (!(MouseEventsToBeProcessed(GUIElements)))
			return;

		// ****************************************************************
		if (MouseEventProcessor.IsRightButtonClicked())
		{
			if (DEFINED(SingleSelectedObject))
			{
				if (SingleSelectedObject.IsNeuron())
				{
					((Neuron) SingleSelectedObject).Toggle(DrawObject.UnZoomPoint(MouseEventProcessor.GetMousePosPoint(GUIElements.GetMainWindow())));

					GUIElements.GetMainWindow().DoRedraw();
				}
				if (SingleSelectedObject.IsNeuronInputField()) // field is now also supported as various DrawObject looping orders changed)
				{
					((NeuronInputField) SingleSelectedObject).Toggle();

					GUIElements.GetMainWindow().DoRedraw();
				}
			}
		}

		return;
	}
}
